package com.wangjiang.mario.admin.core.handler;

import com.wangjiang.mario.admin.common.constant.ProfileConstant;
import com.wangjiang.mario.admin.common.exception.AuthException;
import com.wangjiang.mario.admin.common.exception.NoFoundException;
import com.wangjiang.mario.admin.common.exception.TypeErrorException;
import com.wangjiang.mario.admin.common.rest.ResultGenerator;
import com.wangjiang.mario.admin.common.rest.entity.Result;
import com.wangjiang.mario.admin.common.util.SpringUtil;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * 后面的代码异常处理都加上状态码
 */
@CrossOrigin
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);


    /**
     * 其他统一异常处理
     *
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result processException(
            Exception e,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        e.printStackTrace();

        String error = HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();

        String profile = SpringUtil.getActiveProfile();

        if(Objects.equals(profile, ProfileConstant.DEV)) {
            error += ":" + e.getMessage();
        }

        return ResultGenerator.genInternalErrorResult(error);
    }

//    /**
//     * 空指针异常处理
//     * @param e
//     * @return
//     */
//    @ExceptionHandler(value = NullPointerException.class)
//    @ResponseStatus(HttpStatus.)
//    public Result nullException (
//            NullPointerException e
//    )
//    {
//        e.printStackTrace();
//        logger.error("e:{}",e.getStackTrace().toString());
//        return ResultGenerator.genNoFoundResult(e.getMessage());
//    }

    /**
     * 自定义401异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Result authException(
            AuthException e
    ) {
        e.printStackTrace();
        String error = HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase();

        String profile = SpringUtil.getActiveProfile();

        if(Objects.equals(profile, ProfileConstant.DEV)) {
            error += ":" + e.getMessage();
        }

        return ResultGenerator.genUnauthorizedResult(error);
    }

//    UnauthorizedException
    /**
     * 自定义403异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = UnauthorizedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public Result UnauthorizedException(
            UnauthorizedException e
    ) {
        e.printStackTrace();
        logger.error("e:{}", e.getStackTrace().toString());
        return ResultGenerator.genForbidenResult(e.getMessage());
    }

    /**
     * 自定义404异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = NoFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Result noFoundException(
            NoFoundException e
    ) {
        e.printStackTrace();
        logger.error("e:{}", e.getStackTrace().toString());
        return ResultGenerator.genNoFoundResult(e.getMessage());
    }


    /**
     * 类型不正确异常处理
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = TypeErrorException.class)
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    public Result typeErrorException(
            TypeErrorException e
    ) {

        e.printStackTrace();
        logger.error("e:{}", e.getStackTrace().toString());
        return ResultGenerator.genForbidenResult(HttpStatus.UNSUPPORTED_MEDIA_TYPE.toString());
    }

    @ExceptionHandler(value = UnauthenticatedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public Result UnauthenticatedException(
            UnauthenticatedException e
    ) {

        e.printStackTrace();
        logger.error("e:{}", e.getStackTrace().toString());
        return ResultGenerator.genForbidenResult(HttpStatus.FORBIDDEN.toString());
    }
}
